// ----------------------------------------------------------------------------
// CheckTablespace.java 20101206 ndarkduck version 1.0
// e-mail ndarkduck[ta]gma1l.com, this is a code released under the GPL 3.0
// url: http://code.google.com/p/checkibm/
// and is inspired on the work of: 
// ----------------------------------------------------------------------------
// check_tablespace_db2.java 20100209 frank4dd version 1.0
// ----------------------------------------------------------------------------
// e-mail: support[at]frank4dd.com
// web: http://www.frank4dd.com/howto/nagios/db-monitoring.htm
//
// This nagios plugin queries the DB2 TBSP_UTILIZATION administrative view.
// Supported are DB2 versions 9.x
//
// Pre-requisites: DB2 JDBC driver installed and DB user has these minimum rights:
// SELECT or CONTROL privilege on TBSP_UTILIZATION, SNAPTBSP, SNAPTBSP_PART views
// SELECT or CONTROL privilege on SYSCAT.TABLESPACES catalog view
// SYSMON, SYSCTRL, SYSMAINT, or SYSADM authority to access snapshot monitor data
// ----------------------------------------------------------------------------

package com.google.code.checkibm.db2;

import com.google.code.checkibm.CheckPlugin;
import com.google.code.checkibm.UsageException;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class CheckTablespace implements CheckPlugin
{
    String database         = "";       // db to connect
    String tablespace       = "";       // if we have a ts to specially check
    int return_code         = 3;        // the return code for the plugin
    String message_data     = "";       // the message the user should see on nagios console
    String performance_data = "";       // the variables that should be analized on nagios
    boolean scalevalues     = false;    // If we should use TB, and MB instead of KB when proper
    String used_scale        = "KB";    // If we use scale we start assuming we just need KB
    boolean userpercentage  = false;    // If warn_at and crit_at are in percentage or in KB
    String plugin_usage_msg = "db2_tablespace: -H host -l username -a password\n-F               database=databasename" +
                                "[,scale=true][,percentage=true][,tablespace=tablespacerequired]";       
                                        
    public CheckTablespace(String host, String port,String strargs, 
            String dbUser, String dbPass, float crit_at, float warn_at) throws Exception
    {
        // local parse
        String arguments[] = strargs.split(",");
        String argument[];
        for(int i=0;i<arguments.length;i++)
        {
            argument = arguments[i].split("=");
            if(argument.length<2)
                throw new UsageException(plugin_usage_msg);
            if(argument[0].trim().equals("database"))
                database = argument[1].trim();
            else if(argument[0].trim().equals("scale"))
                scalevalues = true;
            else if(argument[0].trim().equals("percentage"))
                userpercentage = true;
            else if(argument[0].trim().equals("tablespace"))
                tablespace = argument[1].trim();
            
        }
        
        return_code = 0; 
        String query = "";
        
        // Minimal checks
        Class.forName("com.ibm.db2.jcc.DB2Driver"); // throws ClassNotFoundException        
        if (dbUser == "" || dbPass == "" || database == "")            
            throw new UsageException(plugin_usage_msg);
                
        String dbUrl = "jdbc:db2://" + host + ":" + port + "/" + database;
        Connection connection = DriverManager.getConnection(dbUrl, dbUser, dbPass);
        
        //
        
        if(tablespace.equals(""))
            query = "select TBSP_NAME, TBSP_NUM_CONTAINERS, TBSP_TOTAL_SIZE_KB, TBSP_USED_SIZE_KB, TBSP_UTILIZATION_PERCENT FROM SYSIBMADM.TBSP_UTILIZATION where TBSP_TOTAL_SIZE_KB > 0";
        else
            query = "select TBSP_NAME, TBSP_NUM_CONTAINERS, TBSP_TOTAL_SIZE_KB, TBSP_USED_SIZE_KB, TBSP_UTILIZATION_PERCENT FROM SYSIBMADM.TBSP_UTILIZATION where TBSP_NAME = '" + tablespace + "'";
        
        Statement statement = connection.createStatement();
        ResultSet rs = statement.executeQuery(query);
        float tmp_war = 0;
        float tmp_cri = 0;
        while (rs.next())
        {
            // 'label'=value[UOM];warn;crit;min;max
            // '',s,%,B,KB,MB,TB,c
            // null,seconds,percentaje,bytes,kb,mb,tb,continuos

            String tbspname = rs.getString(1);
            int dfiles_total = rs.getInt(2);
            float kbytes_total = (float)rs.getInt(3);
            float kbytes_used = (float)rs.getInt(4);
            float percent_used = (float)rs.getInt(5);            
            //
            if(userpercentage)
            {
                message_data        += tbspname + "="+percent_used+"(dfiles:"+dfiles_total+"). ";
                performance_data    += ""+tbspname+"="+percent_used+"%;"+warn_at+";"+crit_at+";0;100 "; // dfiles:"+dfiles_total;
                if(warn_at>0 || crit_at>0)
                    if(return_code<=1)
                        if(percent_used>=crit_at)
                           return_code=2;
                        else if(percent_used>=warn_at)
                           return_code=1;
            }
            else
            {
                tmp_war = warn_at;
                tmp_cri = crit_at;
                if(scalevalues)
                {
                    if(kbytes_used>1048576 || kbytes_total > 1048576)
                    {
                        tmp_war=tmp_war/1048576;
                        tmp_cri=tmp_cri/1048576;
                        kbytes_used = kbytes_used/1048576;
                        kbytes_total =  kbytes_total/1048576;
                        used_scale = "TB";
                    }
                    else if(kbytes_used>1024 || kbytes_total > 1024)
                    {
                        tmp_war=tmp_war/1024;
                        tmp_cri=tmp_cri/1024;
                        kbytes_used = kbytes_used/1024;
                        kbytes_total =  kbytes_total/1024;
                        used_scale = "MB";
                    }
                }
                if(warn_at>0 || crit_at>0)
                  if(return_code<=1)
                      if(kbytes_used>tmp_cri)
                          return_code=2;
                      else if(kbytes_used>tmp_war)
                          return_code=1;

                performance_data    += ""+tbspname+"="+kbytes_used+used_scale+";"+tmp_war+";"+tmp_cri+";0;"+kbytes_total+" "; 
                message_data        += tbspname + "="+kbytes_used+"/"+kbytes_total+used_scale+" "+"(dfiles:"+dfiles_total+"). ";
            }
            //
        }
        rs.close();
        statement.close();
        connection.close();

    }
    
    public int checkStatus()
    {
        return return_code;
    }
    
    public String get_message()
    {
        return message_data;
    }
    
    public String get_performance_data()
    {      
        return performance_data;
    }
}